package com.iss.card.view.store;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.iss.card.CardController;
import com.iss.card.CardController.EventType;
import com.iss.card.R;
import com.iss.card.common.FunctionUtil;
import com.iss.card.common.IBackKeyListener;
import com.iss.card.mapv2.MyLocationManager;
import com.iss.card.model.CityDataManager;
import com.iss.card.view.model.CityBean;
import com.iss.card.view.overrideview.ListWithSectionAdapter;
import com.iss.card.view.overrideview.ParticipatorSortLetterListView;
import com.iss.card.view.overrideview.ParticipatorSortLetterListView.OnTouchingLetterChangedListener;
import com.iss.card.view.overrideview.ParticipatorSortUtils;

/**
 * show city list.
 */
public class CityListFragment extends Fragment implements IBackKeyListener,
		TextWatcher {
	private static final String TAG = CityListFragment.class.getSimpleName();
	private static final String[] sIndexKeySets = { "A", "B", "C", "D", "E",
			"F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
			"S", "T", "U", "V", "W", "X", "Y", "Z" };

	private Context mContext;
	private EditText mSearchEdit;
	private ListView mSearchListView;
	private ListView mParticipatorSortListView;
	private CityListAdapter mCityListAdapter;
	private ParticipatorSortLetterListView mLetterListView;
	private HanyuPinyinOutputFormat defaultFormat;
	private List<CityBean> mSearchArrayList = new ArrayList<CityBean>();
	private Map<String, List<CityBean>> mContents = new HashMap<String, List<CityBean>>();

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		Log.d(TAG, "onAttach");
		mContext = activity;
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		Log.d(TAG, "onCreateView");
		((Activity) mContext).getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		FrameLayout view = (FrameLayout) inflater.inflate(R.layout.citylist,
				null);
		initView(view);
		defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		return view;
	}

	/**
	 * init view.
	 * 
	 * @param view
	 *            parent view.
	 */
	private void initView(FrameLayout view) {
		mSearchEdit = (EditText) view.findViewById(R.id.search_edit);
		mSearchListView = (ListView) view.findViewById(android.R.id.list);
		mCityListAdapter = new CityListAdapter(mContext, mSearchArrayList);
		mSearchListView.setAdapter(mCityListAdapter);
		// header title.
		TextView title = (TextView) view.findViewById(R.id.job_name_val);
		title.setText(R.string.tab_citylist);

		// return button.
		Button cancel = (Button) view.findViewById(R.id.return_button);
		cancel.setVisibility(View.VISIBLE);
		cancel.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				CardController.getInstance(mContext).sendEvent(
						EventType.STORE_CONTENT);
			}
		});

		mParticipatorSortListView = (ListView) view
				.findViewById(R.id.participator_sort_list);
		mLetterListView = (ParticipatorSortLetterListView) view
				.findViewById(R.id.letter_list_view);
		mLetterListView.setIndexKeysets(sIndexKeySets);
		mLetterListView.setVisibility(View.INVISIBLE);
		mLetterListView
				.setOnTouchingLetterChangedListener(mLetterChangedListener);

		mSearchEdit.addTextChangedListener(this);
		processInfo();

		clickItemEvent();
	}

	/**
	 * listview on item click listener.
	 */
	private void clickItemEvent() {
		mSearchListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				hideSoftwareKeyboard();
				CityBean info = mSearchArrayList.get(position);
				FunctionUtil.setSelectedCityInfo(info);
				CityDataManager.instance().saveRecentlyLocatedCity(info);
				CardController.getInstance(mContext).sendEvent(
						EventType.STORE_CONTENT);
			}
		});

		mParticipatorSortListView
				.setOnItemClickListener(new OnItemClickListener() {

					@Override
					public void onItemClick(AdapterView<?> parent, View view,
							int position, long id) {
						CityBean info = ((CityBean) parent.getAdapter()
								.getItem(position));
						FunctionUtil.setSelectedCityInfo(info);
						CityDataManager.instance()
								.saveRecentlyLocatedCity(info);
						CardController.getInstance(mContext).sendEvent(
								EventType.STORE_CONTENT);
					}
				});
	}

	private void processInfo() {
		mLetterListView.setVisibility(View.VISIBLE);
		List<CityBean> cityList = CityDataManager.instance().getCityList();
		ListWithSectionAdapter adapter = new ListWithSectionAdapter(mContext);
		Resources r = mContext.getResources();
		// located city.
		String cityName = MyLocationManager.instance().getCurrentCityName();
		List<CityBean> deviceLocatedCity = new ArrayList<CityBean>();
		List<CityBean> hotCitys = new ArrayList<CityBean>();
		String key = "";
		for (CityBean info : cityList) {
			if (info.getIsHot()) {
				hotCitys.add(info);
			}
			if (cityName != null && info.getCityName().startsWith(cityName)) {
				deviceLocatedCity.add(info);
			}
		}

		if (deviceLocatedCity.size() > 0) {
			key = r.getString(R.string.citylist_section_title_located_city);
			mContents.put(key, deviceLocatedCity);
			adapter.addSection(key, new CityDisplayedDetailAdapter(mContext,
					deviceLocatedCity));
		}

		// recently located city list.
		List<CityBean> recentlyCity = CityDataManager.instance()
				.getRecentlyLocatedCity();
		Log.d(TAG, "recently size: " + recentlyCity.size());
		if (recentlyCity.size() > 0) {
			key = r.getString(R.string.citylist_section_title_recently_accessed);
			mContents.put(key, recentlyCity);
			adapter.addSection(key, new CityDisplayedDetailAdapter(mContext,
					recentlyCity));
		}
		// hot citys.
		if (hotCitys.size() > 0) {
			key = r.getString(R.string.citylist_section_title_hot_city);
			mContents.put(key, hotCitys);
			adapter.addSection(key, new CityDisplayedDetailAdapter(mContext,
					hotCitys));
		}

		// raw data for city list.
		for (String indexKey : sIndexKeySets) {
			List<CityBean> rawCitys = new ArrayList<CityBean>();
			for (CityBean info : cityList) {
				if (info.getJianpin().startsWith(indexKey)) {
					rawCitys.add(info);
				}
			}

			if (rawCitys.size() > 0) {
				mContents.put(indexKey, rawCitys);
				adapter.addSection(indexKey, new CityDisplayedDetailAdapter(
						mContext, rawCitys));
			}
		}

		mParticipatorSortListView.setAdapter(adapter);
	}

	private void handleSearch(String s) {
		Log.d(TAG, "handleSearch: [" + s + "]");
		mSearchArrayList.clear();
		String sPinyin = ParticipatorSortUtils.doComputeModelFirstLetter(s,
				defaultFormat).toUpperCase();
		for (String key : sIndexKeySets) {
			List<CityBean> list = mContents.get(key);

			if (list == null) {
				continue;
			}
			for (CityBean info : list) {
				Log.d(TAG, "handleSearch:  " + info.getJianpin() + ", "
						+ sPinyin);
				if (info.getJianpin().equals(sPinyin)
						|| info.getJianpin().contains(sPinyin)) {
					mSearchArrayList.add(info);
				}
			}
			Log.d(TAG, "handleSearch:  " + mSearchArrayList.size());
		}

//		if (mSearchArrayList.size() == 0) {
//		} else {
//		}
		mCityListAdapter.notifyDataSetChanged();
	}

	/**
	 * touch listener for right side.
	 */
	private OnTouchingLetterChangedListener mLetterChangedListener = new OnTouchingLetterChangedListener() {
		public void onTouchingLetterChanged(String s) {
			if (mContents.size() == 0) {
				return;
			}

			List<String> keys = new ArrayList<String>();
			keys.addAll(mContents.keySet());
			Collections.sort(keys);
			final int num = keys.size();
			for (int i = 0; i < num; ++i) {
				if (s.equals(keys.get(i))) {
					mParticipatorSortListView.setSelection(i);
					return;
				}
			}
		}
	};

	@Override
	public void cancelUpdate(Object... params) {
		// Tools.onPostCheck((Integer) params[0],null, mContext, tv,-1);
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		if (s.length() == 0) {
			mSearchListView.setVisibility(View.GONE);
			mParticipatorSortListView.setVisibility(View.VISIBLE);
			mLetterListView.setVisibility(View.VISIBLE);
		} else {
			mSearchListView.setVisibility(View.VISIBLE);
			mParticipatorSortListView.setVisibility(View.GONE);
			mLetterListView.setVisibility(View.GONE);
			handleSearch(s.toString());
		}
	}

	@Override
	public void afterTextChanged(Editable s) {

	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "onDestroy");
		hideSoftwareKeyboard();
	}

	private void hideSoftwareKeyboard() {
		((InputMethodManager) mContext
				.getSystemService(Context.INPUT_METHOD_SERVICE))
				.hideSoftInputFromWindow(mSearchEdit.getWindowToken(), 0);
	}

	/**
	 * it is used to bridge for city data and city view.
	 * 
	 * @author dtdh
	 * 
	 */
	private final class CityDisplayedDetailAdapter extends BaseAdapter {
		private List<CityBean> mContents = new ArrayList<CityBean>();
		private Context mContext;

		public CityDisplayedDetailAdapter(Context ct) {
			mContext = ct;
		}

		public CityDisplayedDetailAdapter(Context ct, List<CityBean> datas) {
			mContext = ct;
			setDatas(datas);
		}

		public void setDatas(List<CityBean> datas) {
			mContents.addAll(datas);
		}

		@Override
		public int getCount() {
			return mContents.size();
		}

		@Override
		public Object getItem(int position) {
			return mContents.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder = null;
			if (convertView == null) {
				holder = new ViewHolder();
				convertView = LayoutInflater.from(mContext).inflate(
						R.layout.citylist_item_detail, null);
				holder.mTVCityName = (TextView) convertView
						.findViewById(R.id.cityname);
				holder.mTVStoreNum = (TextView) convertView
						.findViewById(R.id.storescount);
				convertView.setTag(holder);
			}

			holder = (ViewHolder) convertView.getTag();
			CityBean info = mContents.get(position);
			holder.mTVCityName.setText(info.getCityName());
			holder.mTVStoreNum.setText(String.format(mContext.getResources()
					.getString(R.string.city_list_item_store_number), info
					.getStoreNumber()));

			return convertView;
		}

		private final class ViewHolder {
			public TextView mTVCityName;
			public TextView mTVStoreNum;
		}
	}
}
